<script setup lang="ts">
import { ref, onMounted } from "vue";

// 类型定义
interface Point {
  x: number;
  y: number;
}

interface Wall {
  start: Point;
  end: Point;
  thickness: number;
}

interface zhouwangs {
  start: Point;
  end: Point;
  thickness: number;
}

interface DoorWindow {
  position: Point;
  width: number;
  height: number;
  angle: number;
  type: "door" | "window";
}

interface CoordinateSystem {
  scale: number;
  offsetX: number;
  offsetY: number;
  gridSize: number;
}
// 修改类型定义
interface Dimension {
  start: Point;
  end: Point;
  distance: number;
  labelPos: Point;
  orientation: "horizontal" | "vertical";
  side: "top" | "bottom" | "left" | "right";
  isTotal?: boolean; // 新增总尺寸标识
  isFirstDimension?: boolean; // 新增第一道尺寸标识
}

// 新增类型定义
interface AxisLabel {
  position: Point;
  direction: "left" | "right" | "top" | "bottom";
  label: string;
  orientation: "horizontal" | "vertical";
}
// 新增类型定义
interface AxisGroup {
  min: number;
  max: number;
  position: number;
}

// 新增响应式数据
const axisLabels = ref<AxisLabel[]>([]);

// 修改轴号生成逻辑
function generateAxisLabels(): AxisLabel[] {
  const labels: AxisLabel[] = [];
  const buildingBounds = calculateBuildingBounds();
  const thirdDimensionOffset = 400;
  const labelOffset = 80; // 轴号与尺寸线间距

  // 横向轴处理（分左右两侧）
  const horizontalGroups = {
    left: [] as AxisGroup[],
    right: [] as AxisGroup[],
  };

  // 纵向轴处理（分上下两侧）
  const verticalGroups = {
    top: [] as AxisGroup[],
    bottom: [] as AxisGroup[],
  };

  // 分析横向轴网
  zhouwangs.value.forEach((wall) => {
    if (wall.start.y === wall.end.y) {
      // 横向轴
      const y = wall.start.y;
      const minX = Math.min(wall.start.x, wall.end.x);
      const maxX = Math.max(wall.start.x, wall.end.x);

      // 左侧轴判断（轴线左端超出建筑左侧）
      if (minX < buildingBounds.minX) {
        horizontalGroups.left.push({
          min: minX,
          max: maxX,
          position: y,
        });
      }

      // 右侧轴判断（轴线右端超出建筑右侧）
      if (maxX > buildingBounds.maxX) {
        horizontalGroups.right.push({
          min: minX,
          max: maxX,
          position: y,
        });
      }
    }
  });

  // 分析纵向轴网
  zhouwangs.value.forEach((wall) => {
    if (wall.start.x === wall.end.x) {
      // 纵向轴
      const x = wall.start.x;
      const minY = Math.min(wall.start.y, wall.end.y);
      const maxY = Math.max(wall.start.y, wall.end.y);

      // 上侧轴判断（轴线上端超出建筑顶部）
      if (minY < buildingBounds.minY) {
        verticalGroups.top.push({
          min: minY,
          max: maxY,
          position: x,
        });
      }

      // 下侧轴判断（轴线下端超出建筑底部）
      if (maxY > buildingBounds.maxY) {
        verticalGroups.bottom.push({
          min: minY,
          max: maxY,
          position: x,
        });
      }
    }
  });

  // 生成左侧横向轴号（从下到上字母升序）
  horizontalGroups.left
    .sort((a, b) => b.position - a.position) // 从上到下排序
    .forEach((group, index) => {
      const label = String.fromCharCode(65 + index);
      labels.push({
        position: {
          x: buildingBounds.minX - thirdDimensionOffset - labelOffset,
          y: group.position,
        },
        direction: "left",
        label,
        orientation: "vertical",
      });
    });

  // 生成右侧横向轴号（从上到下字母升序）
  horizontalGroups.right
    .sort((a, b) => b.position - a.position) // 从上到下排序
    .forEach((group, index) => {
      const label = String.fromCharCode(65 + index);
      labels.push({
        position: {
          x: buildingBounds.maxX + thirdDimensionOffset + labelOffset,
          y: group.position,
        },
        direction: "right",
        label,
        orientation: "vertical",
      });
    });

  // 生成上侧纵向轴号（从左到右数字升序）
  verticalGroups.top
    .sort((a, b) => a.position - b.position) // 从左到右排序
    .forEach((group, index) => {
      labels.push({
        position: {
          x: group.position,
          y: buildingBounds.minY - thirdDimensionOffset - labelOffset,
        },
        direction: "top",
        label: (index + 1).toString(),
        orientation: "horizontal",
      });
    });

  // 生成下侧纵向轴号（从左到右数字升序）
  verticalGroups.bottom
    .sort((a, b) => a.position - b.position) // 从左到右排序
    .forEach((group, index) => {
      labels.push({
        position: {
          x: group.position,
          y: buildingBounds.maxY + thirdDimensionOffset + labelOffset,
        },
        direction: "bottom",
        label: (index + 1).toString(),
        orientation: "horizontal",
      });
    });

  return labels;
}

// 修改后的绘制函数
function drawAxisLabel(ctx: CanvasRenderingContext2D, label: AxisLabel) {
  const pos = toCanvasCoords(label.position);
  const fontSize = 45 * coordSystem.value.scale;

  ctx.save();
  ctx.font = `${fontSize}px Arial`;
  ctx.fillStyle = "#000";
  ctx.textBaseline = "middle";
  ctx.textAlign = "center";

  // 根据方向调整位置和旋转
  switch (label.direction) {
    case "left":
      ctx.translate(pos.x, pos.y);
      ctx.rotate(-Math.PI / 2);
      ctx.fillText(label.label, 0, -fontSize);
      break;
    case "right":
      ctx.translate(pos.x, pos.y);
      ctx.rotate(Math.PI / 2);
      ctx.fillText(label.label, 0, fontSize);
      break;
    case "top":
      ctx.fillText(label.label, pos.x, pos.y - fontSize);
      break;
    case "bottom":
      ctx.fillText(label.label, pos.x, pos.y + fontSize);
      break;
  }

  ctx.restore();
}

// 响应式数据
const walls = ref<Wall[]>([
  { start: { x: 50, y: 100 }, end: { x: 450, y: 100 }, thickness: 20 },
  { start: { x: 450, y: 100 }, end: { x: 450, y: 400 }, thickness: 20 },
  { start: { x: 450, y: 100 }, end: { x: 750, y: 100 }, thickness: 20 },
  { start: { x: 750, y: 400 }, end: { x: 750, y: 100 }, thickness: 20 },
  { start: { x: 750, y: 100 }, end: { x: 1050, y: 100 }, thickness: 20 },
  { start: { x: 1050, y: 100 }, end: { x: 1300, y: 100 }, thickness: 20 },
  { start: { x: 1300, y: 100 }, end: { x: 1300, y: 1000 }, thickness: 20 },
  { start: { x: 1300, y: 1000 }, end: { x: 50, y: 1000 }, thickness: 20 },
  { start: { x: 50, y: 1000 }, end: { x: 50, y: 100 }, thickness: 20 },
  { start: { x: 50, y: 800 }, end: { x: 350, y: 800 }, thickness: 20 },
  { start: { x: 50, y: 600 }, end: { x: 350, y: 600 }, thickness: 20 },
  { start: { x: 350, y: 600 }, end: { x: 350, y: 700 }, thickness: 20 },
]);
// 响应式数据
const zhouwangs = ref<zhouwangs[]>([
  { start: { x: -50, y: 100 }, end: { x: 1400, y: 100 }, thickness: 1 },
  { start: { x: 450, y: 0 }, end: { x: 450, y: 400 }, thickness: 1 },
  { start: { x: 750, y: 0 }, end: { x: 750, y: 400 }, thickness: 1 },
  { start: { x: 750, y: 100 }, end: { x: 1050, y: 100 }, thickness: 1 },
  { start: { x: -50, y: 1000 }, end: { x: 1400, y: 1000 }, thickness: 1 },
  { start: { x: 50, y: 0 }, end: { x: 50, y: 1100 }, thickness: 1 },
  { start: { x: -50, y: 800 }, end: { x: 350, y: 800 }, thickness: 1 },
  { start: { x: -50, y: 600 }, end: { x: 350, y: 600 }, thickness: 1 },
  { start: { x: 350, y: 0 }, end: { x: 350, y: 700 }, thickness: 1 },
  { start: { x: -50, y: 800 }, end: { x: 350, y: 800 }, thickness: 1 },
  { start: { x: 1300, y: 0 }, end: { x: 1300, y: 1100 }, thickness: 1 },
]);

const doorWindows = ref<DoorWindow[]>([
  {
    position: { x: 200, y: 100 },
    width: 80,
    height: 20,
    angle: 0,
    type: "door",
  },
  {
    position: { x: 450, y: 250 },
    width: 120,
    height: 20,
    angle: 90,
    type: "window",
  },
  {
    position: { x: 600, y: 100 },
    width: 120,
    height: 20,
    angle: 0,
    type: "window",
  },
  {
    position: { x: 750, y: 250 },
    width: 120,
    height: 20,
    angle: 90,
    type: "window",
  },
  {
    position: { x: 900, y: 100 },
    width: 120,
    height: 20,
    angle: 0,
    type: "window",
  },
  {
    position: { x: 1300, y: 600 },
    width: 120,
    height: 20,
    angle: 90,
    type: "window",
  },
  {
    position: { x: 800, y: 1000 },
    width: 120,
    height: 20,
    angle: 0,
    type: "window",
  },
  {
    position: { x: 400, y: 1000 },
    width: 120,
    height: 20,
    angle: 0,
    type: "window",
  },
  {
    position: { x: 50, y: 300 },
    width: 120,
    height: 20,
    angle: 90,
    type: "window",
  },
  {
    position: { x: 50, y: 900 },
    width: 120,
    height: 20,
    angle: 90,
    type: "window",
  },
]);

// 新增建筑边界计算
function calculateBuildingBounds() {
  const allX = walls.value.flatMap((w) => [w.start.x, w.end.x]);
  const allY = walls.value.flatMap((w) => [w.start.y, w.end.y]);
  return {
    minX: Math.min(...allX),
    maxX: Math.max(...allX),
    minY: Math.min(...allY),
    maxY: Math.max(...allY),
  };
}

// 判断是否为外墙
function isExternalWall(
  wall: Wall,
  bounds: ReturnType<typeof calculateBuildingBounds>
): boolean {
  const isHorizontal = wall.start.y === wall.end.y;
  const isVertical = wall.start.x === wall.end.x;

  if (isHorizontal) {
    return wall.start.y === bounds.minY || wall.start.y === bounds.maxY;
  } else if (isVertical) {
    return wall.start.x === bounds.minX || wall.start.x === bounds.maxX;
  }
  return false;
}

// 获取墙体上的门窗
function getDoorsWindowsOnWall(wall: Wall): DoorWindow[] {
  const isHorizontal = wall.start.y === wall.end.y;
  const minX = Math.min(wall.start.x, wall.end.x);
  const maxX = Math.max(wall.start.x, wall.end.x);
  const minY = Math.min(wall.start.y, wall.end.y);
  const maxY = Math.max(wall.start.y, wall.end.y);

  return doorWindows.value.filter((dw) => {
    if (isHorizontal) {
      return (
        dw.position.y === wall.start.y &&
        dw.angle === 0 &&
        dw.position.x >= minX &&
        dw.position.x <= maxX
      );
    } else {
      return (
        dw.position.x === wall.start.x &&
        dw.angle === 90 &&
        dw.position.y >= minY &&
        dw.position.y <= maxY
      );
    }
  });
}

// 生成第一道尺寸
function generateFirstDimensions(): Dimension[] {
  const dimensions: Dimension[] = [];
  const bounds = calculateBuildingBounds();
  const externalWalls = walls.value.filter((wall) =>
    isExternalWall(wall, bounds)
  );

  externalWalls.forEach((wall) => {
    const dws = getDoorsWindowsOnWall(wall);
    const sortedDws = [...dws].sort((a, b) =>
      wall.start.y === wall.end.y
        ? a.position.x - b.position.x
        : a.position.y - b.position.y
    );

    const isHorizontal = wall.start.y === wall.end.y;
    const wallStart = isHorizontal
      ? Math.min(wall.start.x, wall.end.x)
      : Math.min(wall.start.y, wall.end.y);
    const wallEnd = isHorizontal
      ? Math.max(wall.start.x, wall.end.x)
      : Math.max(wall.start.y, wall.end.y);

    let currentPosition = wallStart;
    sortedDws.forEach((dw) => {
      const dwSize = dw.width;
      const dwCenter = isHorizontal ? dw.position.x : dw.position.y;
      const dwStart = dwCenter - dwSize / 2;
      const dwEnd = dwStart + dwSize;

      // 添加墙段
      if (dwStart > currentPosition) {
        dimensions.push(
          createSegmentDimension(wall, currentPosition, dwStart, bounds, false)
        );
      }

      // 添加门窗段
      dimensions.push(
        createSegmentDimension(wall, dwStart, dwEnd, bounds, true)
      );

      currentPosition = dwEnd;
    });

    // 添加最后墙段
    if (currentPosition < wallEnd) {
      dimensions.push(
        createSegmentDimension(wall, currentPosition, wallEnd, bounds, false)
      );
    }
  });

  return dimensions.filter((d) => d !== null) as Dimension[];
}

// 创建分段尺寸
function createSegmentDimension(
  wall: Wall,
  start: number,
  end: number,
  bounds: ReturnType<typeof calculateBuildingBounds>,
  isDoorWindow: boolean
): Dimension | null {
  const length = end - start;
  if (length <= 0) return null;

  const isHorizontal = wall.start.y === wall.end.y;
  const isTop = wall.start.y === bounds.minY;
  const isLeft = wall.start.x === bounds.minX;

  let offset: number;
  let orientation: "horizontal" | "vertical";
  let side: "top" | "bottom" | "left" | "right";
  let startPoint: Point;
  let endPoint: Point;

  if (isHorizontal) {
    orientation = "horizontal";
    offset = isTop ? -200 : 200;
    side = isTop ? "bottom" : "top";
    startPoint = { x: start, y: wall.start.y + offset };
    endPoint = { x: end, y: wall.start.y + offset };
  } else {
    orientation = "vertical";
    offset = isLeft ? -200 : 200;
    side = isLeft ? "right" : "left";
    startPoint = { x: wall.start.x + offset, y: start };
    endPoint = { x: wall.start.x + offset, y: end };
  }

  return {
    start: startPoint,
    end: endPoint,
    distance: length,
    labelPos: calculateLabelPosition(startPoint, endPoint, orientation, side),
    orientation,
    side,
    isFirstDimension: true,
  };
}

// 计算标签位置
function calculateLabelPosition(
  start: Point,
  end: Point,
  orientation: "horizontal" | "vertical",
  side: string
): Point {
  if (orientation === "horizontal") {
    return {
      x: (start.x + end.x) / 2,
      y: side === "top" ? start.y + 30 : start.y - 30,
    };
  } else {
    return {
      x: side === "left" ? start.x - 30 : start.x - 30,
      y: (start.y + end.y) / 2,
    };
  }
}

// 新增响应式数据
const dimensions = ref<Dimension[]>([]);

const coordSystem = ref<CoordinateSystem>({
  scale: 1,
  offsetX: 0,
  offsetY: 0,
  gridSize: 10,
});

const canvasRef = ref<HTMLCanvasElement>();
let isDragging = false;
let lastMouse = { x: 0, y: 0 };

// 坐标转换
function toCanvasCoords(point: Point): Point {
  return {
    x: (point.x - coordSystem.value.offsetX) * coordSystem.value.scale,
    y: (point.y - coordSystem.value.offsetY) * coordSystem.value.scale,
  };
}

// 绘制网格
function drawGrid(ctx: CanvasRenderingContext2D) {
  const { scale, offsetX, offsetY, gridSize } = coordSystem.value;
  const canvas = canvasRef.value!;
  const scaledGrid = gridSize * scale;

  ctx.strokeStyle = "#ddd";
  ctx.lineWidth = 1;

  // 垂直网格
  const startX = Math.floor(offsetX / gridSize) * gridSize;
  for (let x = startX; x < offsetX + canvas.width / scale; x += gridSize) {
    const canvasX = (x - offsetX) * scale;
    ctx.beginPath();
    ctx.moveTo(canvasX, 0);
    ctx.lineTo(canvasX, canvas.height);
    ctx.stroke();
  }

  // 水平网格
  const startY = Math.floor(offsetY / gridSize) * gridSize;
  for (let y = startY; y < offsetY + canvas.height / scale; y += gridSize) {
    const canvasY = (y - offsetY) * scale;
    ctx.beginPath();
    ctx.moveTo(0, canvasY);
    ctx.lineTo(canvas.width, canvasY);
    ctx.stroke();
  }
}

// 绘制坐标轴
function drawAxis(ctx: CanvasRenderingContext2D) {
  const { scale, offsetX, offsetY } = coordSystem.value;
  const canvas = canvasRef.value!;

  ctx.strokeStyle = "#000";
  ctx.setLineDash([5, 5]);

  // X轴
  const originY = (0 - offsetY) * scale;
  ctx.beginPath();
  ctx.moveTo(0, originY);
  ctx.lineTo(canvas.width, originY);
  ctx.stroke();

  // Y轴
  const originX = (0 - offsetX) * scale;
  ctx.beginPath();
  ctx.moveTo(originX, 0);
  ctx.lineTo(originX, canvas.height);
  ctx.stroke();

  ctx.setLineDash([]);
}

// 绘制墙体
function drawWall(ctx: CanvasRenderingContext2D, wall: Wall) {
  const start = toCanvasCoords(wall.start);
  const end = toCanvasCoords(wall.end);

  ctx.beginPath();
  ctx.moveTo(start.x, start.y);
  ctx.lineTo(end.x, end.y);
  ctx.lineWidth = wall.thickness * coordSystem.value.scale;
  ctx.strokeStyle = "#666";
  ctx.stroke();
}
// 绘制轴网
function drawZW(ctx: CanvasRenderingContext2D, wall: Wall) {
  const start = toCanvasCoords(wall.start);
  const end = toCanvasCoords(wall.end);
  ctx.setLineDash([5, 3]);

  ctx.beginPath();
  ctx.moveTo(start.x, start.y);
  ctx.lineTo(end.x, end.y);
  ctx.lineWidth = wall.thickness * coordSystem.value.scale;
  ctx.strokeStyle = "#e04662";
  ctx.stroke();
}

// 绘制门窗
function drawDoorWindow(ctx: CanvasRenderingContext2D, dw: DoorWindow) {
  const pos = toCanvasCoords(dw.position);

  ctx.save();
  ctx.translate(pos.x, pos.y);
  ctx.rotate((dw.angle * Math.PI) / 180);
  ctx.scale(coordSystem.value.scale, coordSystem.value.scale);

  ctx.fillStyle = dw.type === "door" ? "#d08" : "#39f";
  ctx.fillRect(-dw.width / 2, -dw.height / 2, dw.width, dw.height);

  ctx.restore();
}

// 在 generateDimensions 函数中添加以下内容
function generateDimensions(): Dimension[] {
  const dims: Dimension[] = [];
  const planeBounds = calculatePlaneBounds();
  // 生成第一道尺寸（最内层）
  dims.push(...generateFirstDimensions());

  // 处理横向轴网（水平方向） ==============================
  const horizontalGroups = groupHorizontalAxes();

  // 右侧标注处理
  const rightSideY = Array.from(horizontalGroups.entries())
    .filter(([y, group]) => group.maxX === planeBounds.maxX)
    .map(([y]) => y)
    .sort((a, b) => a - b);

  // 生成右侧纵向间距标注
  for (let i = 0; i < rightSideY.length - 1; i++) {
    const currentY = rightSideY[i];
    const nextY = rightSideY[i + 1];
    dims.push(
      createVerticalDimension(planeBounds.maxX + 200, currentY, nextY, "right")
    );
  }

  // 左侧标注处理（新增代码）
  const leftSideY = Array.from(horizontalGroups.entries())
    .filter(([y, group]) => group.minX === planeBounds.minX)
    .map(([y]) => y)
    .sort((a, b) => a - b);

  // 生成左侧纵向间距标注
  for (let i = 0; i < leftSideY.length - 1; i++) {
    const currentY = leftSideY[i];
    const nextY = leftSideY[i + 1];
    dims.push(
      createVerticalDimension(planeBounds.minX - 200, currentY, nextY, "left")
    );
  }

  // 处理纵向轴网（垂直方向） ==============================
  const verticalGroups = groupVerticalAxes();

  // 上方标注处理
  const topSideX = Array.from(verticalGroups.entries())
    .filter(([x, group]) => group.maxY === planeBounds.maxY)
    .map(([x]) => x)
    .sort((a, b) => a - b);

  // 生成上方横向间距标注
  for (let i = 0; i < topSideX.length - 1; i++) {
    const currentX = topSideX[i];
    const nextX = topSideX[i + 1];
    dims.push(
      createHorizontalDimension(planeBounds.maxY + 200, currentX, nextX, "top")
    );
  }

  // 下方标注处理（新增代码）
  const bottomSideX = Array.from(verticalGroups.entries())
    .filter(([x, group]) => group.minY === planeBounds.minY)
    .map(([x]) => x)
    .sort((a, b) => a - b);

  // 生成下方横向间距标注
  for (let i = 0; i < bottomSideX.length - 1; i++) {
    const currentX = bottomSideX[i];
    const nextX = bottomSideX[i + 1];
    dims.push(
      createHorizontalDimension(
        planeBounds.minY - 200,
        currentX,
        nextX,
        "bottom"
      )
    );
  }

  // 新增第三道总尺寸 ==============================
  // 获取实际建筑边界（基于第二道尺寸的标注范围）
  const buildingBounds = getActualBuildingBounds(dims);

  // 生成右侧总尺寸
  dims.push(
    createTotalDimension(
      "right",
      planeBounds.maxX + 300,
      buildingBounds.actualMinY,
      buildingBounds.actualMaxY,
      buildingBounds.totalWidth
    )
  );

  // 生成左侧总尺寸
  dims.push(
    createTotalDimension(
      "left",
      planeBounds.minX - 300,
      buildingBounds.actualMinY,
      buildingBounds.actualMaxY,
      buildingBounds.totalWidth
    )
  );

  // 生成上方总尺寸
  dims.push(
    createTotalDimension(
      "top",
      planeBounds.maxY + 300,
      buildingBounds.actualMinX,
      buildingBounds.actualMaxX,
      buildingBounds.totalHeight
    )
  );

  // 生成下方总尺寸
  dims.push(
    createTotalDimension(
      "bottom",
      planeBounds.minY - 300,
      buildingBounds.actualMinX,
      buildingBounds.actualMaxX,
      buildingBounds.totalHeight
    )
  );

  return dims;
}

// 新增辅助函数
function calculatePlaneBounds() {
  const allX = zhouwangs.value.flatMap((w) => [w.start.x, w.end.x]);
  const allY = zhouwangs.value.flatMap((w) => [w.start.y, w.end.y]);
  return {
    minX: Math.min(...allX),
    maxX: Math.max(...allX),
    minY: Math.min(...allY),
    maxY: Math.max(...allY),
  };
}

// 优化后的分组函数
function groupHorizontalAxes() {
  const groups = new Map<number, { minX: number; maxX: number }>();
  zhouwangs.value.forEach((wall) => {
    if (wall.start.y === wall.end.y) {
      const y = wall.start.y;
      const currentMin = Math.min(wall.start.x, wall.end.x);
      const currentMax = Math.max(wall.start.x, wall.end.x);

      if (!groups.has(y)) {
        groups.set(y, { minX: currentMin, maxX: currentMax });
      } else {
        const existing = groups.get(y)!;
        groups.set(y, {
          minX: Math.min(existing.minX, currentMin),
          maxX: Math.max(existing.maxX, currentMax),
        });
      }
    }
  });
  return groups;
}

function groupVerticalAxes() {
  const groups = new Map<number, { minY: number; maxY: number }>();
  zhouwangs.value.forEach((wall) => {
    if (wall.start.x === wall.end.x) {
      const x = wall.start.x;
      const minY = Math.min(wall.start.y, wall.end.y);
      const maxY = Math.max(wall.start.y, wall.end.y);
      if (groups.has(x)) {
        const existing = groups.get(x)!;
        groups.set(x, {
          minY: Math.min(existing.minY, minY),
          maxY: Math.max(existing.maxY, maxY),
        });
      } else {
        groups.set(x, { minY, maxY });
      }
    }
  });
  return groups;
}

function createVerticalDimension(
  baseX: number,
  y1: number,
  y2: number,
  side: "left" | "right"
) {
  return {
    start: { x: baseX, y: y1 },
    end: { x: baseX, y: y2 },
    distance: y2 - y1,
    labelPos: {
      x: side === "left" ? baseX - 20 : baseX - 20,
      y: (y1 + y2) / 2,
    },
    orientation: "vertical",
    side,
  };
}

function createHorizontalDimension(
  baseY: number,
  x1: number,
  x2: number,
  side: "top" | "bottom"
) {
  return {
    start: { x: x1, y: baseY },
    end: { x: x2, y: baseY },
    distance: x2 - x1,
    labelPos: {
      x: (x1 + x2) / 2,
      y: side === "bottom" ? baseY - 20 : baseY + 20,
    },
    orientation: "horizontal",
    side,
  };
}

// 修改后的绘制函数
function drawDimension(ctx: CanvasRenderingContext2D, dim: Dimension) {
  const start = toCanvasCoords(dim.start);
  const end = toCanvasCoords(dim.end);
  const labelPos = toCanvasCoords(dim.labelPos);

  // 绘制尺寸线
  ctx.strokeStyle = "#333";
  ctx.lineWidth = 1;
  ctx.beginPath();
  ctx.moveTo(start.x, start.y);
  ctx.lineTo(end.x, end.y);
  ctx.stroke();

  // 针对总尺寸的特殊处理
  if (dim.isTotal) {
    ctx.strokeStyle = "#f00"; // 总尺寸用红色区分
    ctx.lineWidth = 2 * coordSystem.value.scale;

    // 绘制总尺寸箭头
    drawDimensionArrow(ctx, dim);
  }

  // 绘制标注文字
  ctx.fillStyle = "#333";
  ctx.font = `${45 * coordSystem.value.scale}px Arial`;
  ctx.textBaseline = "middle";

  if (dim.orientation === "horizontal") {
    ctx.textAlign = "center";
    // 上方标注文字在下侧，下方标注文字在上侧
    const offsetY = dim.side === "bottom" ? -20 : 20;
    ctx.fillText(
      dim.distance.toString(),
      labelPos.x,
      labelPos.y + offsetY * coordSystem.value.scale
    );

    // 绘制两端的标记线
    [start, end].forEach((point) => {
      ctx.beginPath();
      ctx.moveTo(point.x, point.y - 5);
      ctx.lineTo(point.x, point.y + 5);
      ctx.stroke();
    });
  } else {
    ctx.textAlign = dim.side === "left" ? "right" : "right";
    const offsetX = dim.side === "left" ? -12 : -12;

    ctx.save();
    ctx.translate(labelPos.x, labelPos.y);
    ctx.rotate(-Math.PI / 2);
    ctx.fillText(dim.distance.toString(), offsetX * coordSystem.value.scale, 0);
    ctx.restore();

    // 绘制两端的标记线
    [start, end].forEach((point) => {
      ctx.beginPath();
      ctx.moveTo(point.x - 5, point.y);
      ctx.lineTo(point.x + 5, point.y);
      ctx.stroke();
    });
  }
  // 设置样式
  if (dim.isFirstDimension) {
    ctx.strokeStyle = "#00f";
    ctx.fillStyle = "#00f";
  } else if (dim.isTotal) {
    ctx.strokeStyle = "#f00";
    ctx.fillStyle = "#f00";
  } else {
    ctx.strokeStyle = "#333";
    ctx.fillStyle = "#333";
  }
}

// 新增实际建筑边界计算
function getActualBuildingBounds(dimensions: Dimension[]) {
  // 从第二道尺寸中提取有效范围
  const secondDims = dimensions.filter((d) => !d.isTotal);

  // 初始化边界值
  const bounds = {
    actualMinX: Infinity,
    actualMaxX: -Infinity,
    actualMinY: Infinity,
    actualMaxY: -Infinity,
    totalWidth: 0,
    totalHeight: 0,
  };

  // 处理横向尺寸
  const xDims = secondDims.filter((d) => d.orientation === "horizontal");
  if (xDims.length > 0) {
    const xValues = xDims.flatMap((d) => [d.start.x, d.end.x]);
    bounds.actualMinX = Math.min(...xValues);
    bounds.actualMaxX = Math.max(...xValues);
    bounds.totalWidth = bounds.actualMaxX - bounds.actualMinX;
  }

  // 处理纵向尺寸
  const yDims = secondDims.filter((d) => d.orientation === "vertical");
  if (yDims.length > 0) {
    const yValues = yDims.flatMap((d) => [d.start.y, d.end.y]);
    bounds.actualMinY = Math.min(...yValues);
    bounds.actualMaxY = Math.max(...yValues);
    bounds.totalHeight = bounds.actualMaxY - bounds.actualMinY;
  }

  return bounds;
}

// 修改总尺寸创建函数
function createTotalDimension(
  side: "top" | "bottom" | "left" | "right",
  position: number,
  startVal: number,
  endVal: number,
  distance: number // 直接使用计算好的总尺寸值
): Dimension {
  const isVertical = side === "left" || side === "right";

  return {
    start: isVertical
      ? { x: position, y: startVal }
      : { x: startVal, y: position },
    end: isVertical ? { x: position, y: endVal } : { x: endVal, y: position },
    distance,
    labelPos: calculateTotalLabelPos(side, position, startVal, endVal),
    orientation: isVertical ? "vertical" : "horizontal",
    side,
    isTotal: true,
  };
}

// 计算总尺寸标签位置
function calculateTotalLabelPos(
  side: string,
  position: number,
  start: number,
  end: number
): Point {
  const mid = (start + end) / 2;
  switch (side) {
    case "right":
      return { x: position - 20, y: mid };
    case "left":
      return { x: position - 20, y: mid };
    case "top":
      return { x: mid, y: position + 20 };
    case "bottom":
      return { x: mid, y: position - 20 };
    default:
      return { x: 0, y: 0 };
  }
}

// 主绘制函数
function draw() {
  if (!canvasRef.value) return;
  const ctx = canvasRef.value.getContext("2d");
  if (!ctx) return;

  ctx.clearRect(0, 0, canvasRef.value.width, canvasRef.value.height);

  drawGrid(ctx);
  drawAxis(ctx);
  walls.value.forEach((wall) => drawWall(ctx, wall));
  zhouwangs.value.forEach((zhouwang) => drawZW(ctx, zhouwang));
  doorWindows.value.forEach((dw) => drawDoorWindow(ctx, dw));
  dimensions.value.forEach((dim) => drawDimension(ctx, dim)); // 新增标注绘制
  axisLabels.value.forEach((label) => drawAxisLabel(ctx, label)); // 新增轴号绘制
}

// 新增箭头绘制函数
function drawDimensionArrow(ctx: CanvasRenderingContext2D, dim: Dimension) {
  const arrowSize = 8 * coordSystem.value.scale;
  const start = toCanvasCoords(dim.start);
  const end = toCanvasCoords(dim.end);

  if (dim.orientation === "horizontal") {
    // 水平尺寸箭头
    ctx.beginPath();
    ctx.moveTo(start.x, start.y);
    ctx.lineTo(start.x + arrowSize, start.y - arrowSize);
    ctx.moveTo(start.x, start.y);
    ctx.lineTo(start.x + arrowSize, start.y + arrowSize);

    ctx.moveTo(end.x, end.y);
    ctx.lineTo(end.x - arrowSize, end.y - arrowSize);
    ctx.moveTo(end.x, end.y);
    ctx.lineTo(end.x - arrowSize, end.y + arrowSize);
  } else {
    // 垂直尺寸箭头
    ctx.beginPath();
    ctx.moveTo(start.x, start.y);
    ctx.lineTo(start.x - arrowSize, start.y + arrowSize);
    ctx.moveTo(start.x, start.y);
    ctx.lineTo(start.x + arrowSize, start.y + arrowSize);

    ctx.moveTo(end.x, end.y);
    ctx.lineTo(end.x - arrowSize, end.y - arrowSize);
    ctx.moveTo(end.x, end.y);
    ctx.lineTo(end.x + arrowSize, end.y - arrowSize);
  }
  ctx.stroke();
}

// 交互事件处理
function handleWheel(e: WheelEvent) {
  e.preventDefault();
  const delta = e.deltaY > 0 ? 0.9 : 1.1;
  coordSystem.value.scale *= delta;
  draw();
}

function handleMouseDown(e: MouseEvent) {
  isDragging = true;
  lastMouse = { x: e.clientX, y: e.clientY };
}

function handleMouseMove(e: MouseEvent) {
  if (!isDragging) return;

  const dx = (e.clientX - lastMouse.x) / coordSystem.value.scale;
  const dy = (e.clientY - lastMouse.y) / coordSystem.value.scale;

  coordSystem.value.offsetX -= dx;
  coordSystem.value.offsetY -= dy;
  lastMouse = { x: e.clientX, y: e.clientY };
  draw();
}

function handleMouseUp() {
  isDragging = false;
}

// 初始化
onMounted(() => {
  coordSystem.value.offsetX = -400;
  coordSystem.value.offsetY = -300;
  dimensions.value = generateDimensions();
  axisLabels.value = generateAxisLabels(); // 新增轴号生成
  draw();
});
</script>

<template>
  <div class="cad-container">
    <div class="coord-info">
      缩放: {{ coordSystem.scale.toFixed(2) }}x | 偏移: ({{
        coordSystem.offsetX.toFixed(1)
      }}, {{ coordSystem.offsetY.toFixed(1) }})
    </div>
    <canvas
      ref="canvasRef"
      width="800"
      height="600"
      @wheel="handleWheel"
      @mousedown="handleMouseDown"
      @mousemove="handleMouseMove"
      @mouseup="handleMouseUp"
      @mouseleave="handleMouseUp"
    ></canvas>
  </div>
</template>

<style scoped>
.cad-container {
  position: relative;
  margin: 20px;
}

canvas {
  border: 1px solid #ccc;
  background: #f8f8f8;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}

.coord-info {
  position: absolute;
  bottom: 10px;
  left: 10px;
  background: rgba(255, 255, 255, 0.9);
  padding: 8px 12px;
  border-radius: 4px;
  font-family: monospace;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  z-index: 1;
}
</style>
